<template>
  <div class="role-manager">
    <div class="role-header">
      <div class="search-section">
        <input
          v-model="searchQuery"
          placeholder="搜索角色..."
          class="search-input"
        />
        <select v-model="teamFilter" class="team-filter">
          <option value="">所有阵营</option>
          <option value="townsfolk">镇民</option>
          <option value="outsider">外来者</option>
          <option value="minion">爪牙</option>
          <option value="demon">恶魔</option>
          <option value="traveler">旅行者</option>
          <option value="fabled">传奇角色</option>
        </select>
        <select v-model="roleTypeFilter" class="role-type-filter">
          <option value="">所有类型</option>
          <option value="official">🏛️ 官方角色</option>
          <option value="custom">🔧 自定义角色</option>
        </select>
      </div>
      
      <!-- 批量操作区域 -->
      <div class="batch-actions" v-if="selectedRoles.length > 0">
        <div class="selection-info">
          <span class="selected-count">已选择 {{ selectedRoles.length }} 个角色</span>
          <button @click="clearSelection" class="clear-selection">清除选择</button>
        </div>
        <div class="batch-buttons">
          <button @click="batchDelete" class="batch-delete-btn">
            🗑️ 批量删除 ({{ selectedRoles.length }})
          </button>
          <button @click="batchExport" class="batch-export-btn">
            📤 导出选中
          </button>
        </div>
      </div>
      
      <!-- 用户提示信息 -->
      <div class="info-banner" v-if="allRoles.length === 0">
        <div class="banner-content">
          <h3>🎭 欢迎使用全新的角色管理系统！</h3>
          <p>现在所有角色都由您来管理，包括官方角色和自定义角色。</p>
          <div class="info-actions">
            <button @click="showOfficialRolesInfo = !showOfficialRolesInfo" class="info-btn">
              📖 如何获取官方角色？
            </button>
            <button @click="showScriptImport = true" class="import-btn">
              📥 导入角色数据
            </button>
          </div>
        </div>
        
        <div v-if="showOfficialRolesInfo" class="official-roles-info">
          <h4>🏛️ 获取官方角色数据：</h4>
          <ol>
            <li><strong>下载模板：</strong>
              <a href="/official-roles-template.json" download class="download-link">
                官方角色模板文件 (official-roles-template.json)
              </a>
            </li>
            <li><strong>导入角色：</strong>使用"剧本导入角色"功能上传JSON文件</li>
            <li><strong>设置类型：</strong>角色会自动标记为"官方"类型</li>
            <li><strong>完善数据：</strong>您可以根据需要添加更多官方角色或修改描述</li>
          </ol>
          <p class="tip">💡 提示：您也可以从血染钟楼官网或其他来源获取更完整的官方角色数据。</p>
        </div>
      </div>

      <div class="header-actions">

        <button @click="toggleSelectAll" class="select-all-btn" :class="{ active: isAllSelected }">
          {{ isAllSelected ? '取消全选' : '全选角色' }}
        </button>
        <button @click="showScriptImport = true" class="import-btn">剧本导入角色</button>
        <button @click="exportRoles" class="export-btn">导出角色</button>
      <button @click="showAddRole = true" class="add-btn">添加角色</button>
      </div>
    </div>

    <div class="role-list" :key="forceUpdateKey">
      <div
        v-for="role in filteredRoles"
        :key="role.id + '_' + forceUpdateKey"
        class="role-item"
        :class="{ 'selected': selectedRoles.includes(role.id) }"
        @click="editRole(role)"
      >
        <!-- 角色选择复选框 -->
        <div class="role-selection" @click.stop>
          <label class="role-checkbox">
            <input 
              type="checkbox" 
              :value="role.id"
              v-model="selectedRoles"
              @change="updateSelection"
            />
            <span class="checkbox-custom"></span>
          </label>
        </div>

        <div class="role-icon">
          <img
            :src="getRoleIcon(role.id)"
            :alt="role.name"
            @error="handleImageError"
            @load="handleImageLoad"
            class="role-image"
            loading="lazy"
          />
          <div class="image-loading" v-if="imageLoadingStates[role.id]">📷</div>
        </div>
        <div class="role-header">
          <div class="role-title">
          <h4>{{ role.name }}</h4>
            <span v-if="isOfficialRole(role.id)" class="role-badge official" title="官方角色">官方</span>
            <span v-else class="role-badge custom" title="自定义角色">自定义</span>
          </div>
          <p class="role-team">{{ getTeamName(role.team) }}</p>
        </div>
        <div class="role-ability-container">
          <p class="role-ability">
            {{ role.ability }}
          </p>
        </div>
        <div class="role-actions">
          <button @click.stop="editRole(role)" class="edit-btn">编辑</button>
          <button @click.stop="deleteRole(role)" class="delete-btn">
            删除
          </button>
        </div>
      </div>

      <!-- 空状态显示 -->
      <div v-if="filteredRoles.length === 0" class="empty-state">
        <div class="empty-icon">🎭</div>
        <h3>暂无角色</h3>
        <p>{{ searchQuery || teamFilter ? '没有找到匹配的角色' : '还没有角色，快来添加第一个角色吧！' }}</p>
        <button v-if="!searchQuery && !teamFilter" @click="showAddRole = true" class="add-first-role">
          ✨ 添加角色
        </button>
      </div>
    </div>

    <!-- 添加/编辑角色模态框 -->
    <div v-if="showAddRole || editingRole" class="role-modal">
      <div class="modal-content">
        <div class="modal-header">
          <h3>{{ editingRole ? "编辑角色" : "添加角色" }}</h3>
          <button @click="cancelEdit" class="close-btn">×</button>
        </div>

        <div class="form-group">
          <label>角色ID:</label>
          <input v-model="roleForm.id" placeholder="角色唯一标识符" />
        </div>

        <div class="form-group">
          <label>角色名称:</label>
          <input v-model="roleForm.name" placeholder="角色显示名称" />
        </div>

        <div class="form-group">
          <label>角色图标 URL:</label>
          <div class="logo-input-group">
            <input v-model="roleForm.image" placeholder="角色图标地址 (可选)" class="logo-input" />
            <div class="logo-preview" v-if="roleForm.image">
              <img :src="roleForm.image" :alt="roleForm.name" @error="handleLogoError" />
            </div>
          </div>
          <small class="form-hint">留空将使用默认图标，支持 .png、.jpg、.webp 等格式</small>
        </div>

        <div class="form-group">
          <label>阵营:</label>
          <select v-model="roleForm.team">
            <option value="townsfolk">镇民</option>
            <option value="outsider">外来者</option>
            <option value="minion">爪牙</option>
            <option value="demon">恶魔</option>
            <option value="traveler">旅行者</option>
            <option value="fabled">传奇角色</option>
          </select>
        </div>

        <div class="form-group">
          <label>角色类型:</label>
          <select v-model="roleForm.roleType" class="role-type-select">
            <option value="official">🏛️ 官方角色</option>
            <option value="custom">🔧 自定义角色</option>
          </select>
          <small class="form-hint">选择角色类型标签，用于分类和管理</small>
        </div>

        <div class="form-group">
          <label>能力描述:</label>
          <textarea
            v-model="roleForm.ability"
            placeholder="角色能力描述"
          ></textarea>
        </div>

        <div class="form-group">
          <label>首夜行动顺序:</label>
          <input
            v-model="roleForm.firstNight"
            type="number"
            placeholder="0表示不行动"
          />
        </div>

        <div class="form-group">
          <label>其他夜晚行动顺序:</label>
          <input
            v-model="roleForm.otherNight"
            type="number"
            placeholder="0表示不行动"
          />
        </div>

        <div class="form-group">
          <label>首夜提醒:</label>
          <textarea
            v-model="roleForm.firstNightReminder"
            placeholder="首夜提醒文本"
          ></textarea>
        </div>

        <div class="form-group">
          <label>其他夜晚提醒:</label>
          <textarea
            v-model="roleForm.otherNightReminder"
            placeholder="其他夜晚提醒文本"
          ></textarea>
        </div>

        <div class="form-group">
          <label>提醒标记:</label>
          <input
            v-model="roleForm.reminders"
            placeholder="用逗号分隔多个标记"
          />
        </div>

        <div class="form-group">
          <label>
            <input v-model="roleForm.setup" type="checkbox" />
            影响游戏设置
          </label>
        </div>

        <div class="modal-actions">
          <button @click="saveRole" class="save-btn">保存</button>
          <button @click="cancelEdit" class="cancel-btn">取消</button>
        </div>
      </div>
    </div>

    <!-- 剧本导入角色模态框 -->
    <div v-if="showScriptImport" class="role-modal">
      <div class="modal-content">
        <div class="modal-header">
          <h3>剧本导入角色</h3>
          <button @click="cancelScriptImport" class="close-btn">×</button>
        </div>

        <div class="import-section">
          <div class="form-group">
            <label>选择剧本文件:</label>
            <input type="file" @change="handleScriptFile" accept=".json" class="file-input" />
            <small class="form-hint">支持 JSON 格式的剧本文件</small>
          </div>

          <div v-if="scriptPreview.length > 0" class="preview-section">
            <h4>预览角色 ({{ scriptPreview.length }} 个):</h4>
            <div class="script-roles-grid">
              <div v-for="role in scriptPreview" :key="role.id" class="preview-role">
                <div class="preview-role-icon">
                  <img :src="getPreviewRoleIcon(role)" :alt="role.name" @error="handlePreviewImageError" />
                </div>
                <div class="preview-role-info">
                  <strong>{{ role.name || role.id }}</strong>
                  <div class="preview-role-team">{{ getTeamName(role.team) }}</div>
                  <div class="preview-role-ability">{{ role.ability || '无能力描述' }}</div>
                </div>
                <div class="preview-role-actions">
                  <label class="import-checkbox">
                    <input type="checkbox" v-model="role.selected" />
                    <span>导入</span>
                  </label>
                </div>
              </div>
            </div>
            
            <div class="import-actions">
              <button @click="selectAllRoles" class="action-btn">全选</button>
              <button @click="deselectAllRoles" class="action-btn">取消全选</button>
              <button @click="importSelectedRoles" class="import-roles-btn" :disabled="!hasSelectedRoles">
                导入选中角色 ({{ selectedRolesCount }})
              </button>
            </div>
          </div>
        </div>

        <div class="modal-actions">
          <button @click="cancelScriptImport" class="cancel-btn">取消</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "RoleManager",
  data() {
    return {
      searchQuery: "",
      teamFilter: "",
      roleTypeFilter: "", // 新增：角色类型过滤器
      showAddRole: false,
      showScriptImport: false,
      showOfficialRolesInfo: false, // 显示官方角色获取信息
      editingRole: null,
      scriptPreview: [],
      selectedRoles: [], // 选中的角色ID数组
      forceUpdateKey: 0, // 用于强制更新UI的key
      imageLoadingStates: {}, // 图片加载状态
      roleForm: {
        id: "",
        name: "",
        image: "",
        team: "townsfolk",
        ability: "",
        firstNight: 0,
        otherNight: 0,
        firstNightReminder: "",
        otherNightReminder: "",
        reminders: "",
        setup: false,
        roleType: "custom", // 新增：角色类型标签 ('official' | 'custom')
      },
      isLoading: false,
    };
  },
  computed: {
    allRoles() {
      return Array.from(this.$store.getters.rolesJSONbyId.values());
    },
    filteredRoles() {
      let roles = this.allRoles;

      if (this.searchQuery) {
        roles = roles.filter(
          (role) =>
            role.name.toLowerCase().includes(this.searchQuery.toLowerCase()) ||
            role.ability.toLowerCase().includes(this.searchQuery.toLowerCase()),
        );
      }

      if (this.teamFilter) {
        roles = roles.filter((role) => role.team === this.teamFilter);
      }

      if (this.roleTypeFilter) {
        roles = roles.filter((role) => {
          // 使用isOfficialRole方法判断角色类型
          const isOfficial = this.isOfficialRole(role.id);
          return this.roleTypeFilter === 'official' ? isOfficial : !isOfficial;
        });
      }

      return roles.sort((a, b) => a.name.localeCompare(b.name));
    },
    hasSelectedRoles() {
      return this.scriptPreview.some(role => role.selected);
    },
    selectedRolesCount() {
      return this.scriptPreview.filter(role => role.selected).length;
    },
    // 批量选择相关计算属性
    isAllSelected() {
      return this.filteredRoles.length > 0 && this.selectedRoles.length === this.filteredRoles.length;
    },
    isPartialSelected() {
      return this.selectedRoles.length > 0 && this.selectedRoles.length < this.filteredRoles.length;
    },
    selectedRoleObjects() {
      return this.filteredRoles.filter(role => this.selectedRoles.includes(role.id));
    },
  },
  watch: {
    // 监听搜索和过滤条件变化，自动清理无效选择
    searchQuery() {
      this.updateSelection();
    },
    teamFilter() {
      this.updateSelection();
    },
    roleTypeFilter() {
      this.updateSelection();
    },
    // 监听角色数据变化
    allRoles() {
      this.updateSelection();
    }
  },
  methods: {
    getTeamName(team) {
      const teamNames = {
        townsfolk: "镇民",
        outsider: "外来者",
        minion: "爪牙",
        demon: "恶魔",
        traveler: "旅行者",
        fabled: "传奇角色",
      };
      return teamNames[team] || team;
    },
    getRoleIcon(roleId) {
      // 获取角色对象
      const role = this.$store.getters.rolesJSONbyId.get(roleId);
      
      // 设置加载状态
      this.$set(this.imageLoadingStates, roleId, true);
      
      // 在下一个tick中添加加载状态样式
      this.$nextTick(() => {
        this.updateRoleIconState(roleId, 'loading');
      });
      
      // 详细的调试输出
      if (role) {
        console.log(`🔍 角色 ${roleId} 数据:`, {
          hasImage: !!role.image,
          imageValue: role.image,
          hasAbility: !!role.ability,
          abilityPreview: role.ability?.substring(0, 50) + '...',
          isCustom: role.isCustom,
          roleType: role.roleType
        });
      } else {
        console.warn(`⚠️ 找不到角色 ${roleId} 的数据`);
      }
      
      // 优先使用角色的自定义图片
      if (role && role.image) {
        console.log(`✅ 使用角色 ${roleId} 的自定义图片:`, role.image);
        return role.image;
      }
      
      // 如果没有自定义图片，尝试使用本地assets图片
      try {
        const localIcon = require(`../../assets/icons/${roleId}.png`);
        console.log(`📁 使用角色 ${roleId} 的本地图片:`, localIcon);
        return localIcon;
      } catch {
        console.log(`🎨 角色 ${roleId} 使用默认图片`);
        // 默认图片不需要加载状态
        this.$set(this.imageLoadingStates, roleId, false);
        this.$nextTick(() => {
          this.updateRoleIconState(roleId, 'clear');
        });
        return require("../../assets/icons/custom.png");
      }
    },
    handleImageError(event) {
      const roleElement = event.target.closest('.role-item');
      const roleId = roleElement?.querySelector('input[type="checkbox"]')?.value;
      
      console.log(`图片加载失败，角色ID: ${roleId}，尝试的URL: ${event.target.src}`);
      
      // 如果是自定义图片失败，尝试本地图片
      if (roleId && event.target.src !== require("../../assets/icons/custom.png")) {
        try {
          const localIcon = require(`../../assets/icons/${roleId}.png`);
          console.log(`回退到本地图片: ${localIcon}`);
          event.target.src = localIcon;
          return;
        } catch {
          // 本地图片也不存在，使用默认图片
        }
      }
      
      // 最终回退到默认图片
      console.log(`使用默认图片作为最终回退`);
      event.target.src = require("../../assets/icons/custom.png");
      
      // 添加错误样式类
      event.target.classList.add('image-error');
      
      // 清除加载状态
      if (roleId) {
        this.$set(this.imageLoadingStates, roleId, false);
        this.updateRoleIconState(roleId, 'error');
      }
    },
    
    handleImageLoad(event) {
      const roleElement = event.target.closest('.role-item');
      const roleId = roleElement?.querySelector('input[type="checkbox"]')?.value;
      
      console.log(`图片加载成功，角色ID: ${roleId}，URL: ${event.target.src}`);
      
      // 清除加载状态和错误样式
      if (roleId) {
        this.$set(this.imageLoadingStates, roleId, false);
        this.updateRoleIconState(roleId, 'success');
      }
      event.target.classList.remove('image-error');
    },
    
    // 更新角色图标状态样式
    updateRoleIconState(roleId, state) {
      this.$nextTick(() => {
        const roleElements = document.querySelectorAll(`input[value="${roleId}"]`);
        roleElements.forEach(checkbox => {
          const roleItem = checkbox.closest('.role-item');
          const roleIcon = roleItem?.querySelector('.role-icon');
          
          if (roleIcon) {
            // 清除所有状态类
            roleIcon.classList.remove('loading-state', 'error-state');
            
            // 添加对应状态类
            switch (state) {
              case 'loading':
                roleIcon.classList.add('loading-state');
                break;
              case 'error':
                roleIcon.classList.add('error-state');
                break;
              case 'success':
              case 'clear':
                // 成功或清除状态不需要特殊样式
                break;
            }
          }
        });
      });
    },
    editRole(role) {
      this.editingRole = role;
      this.roleForm = {
        id: role.id,
        name: role.name,
        image: role.image || "",
        team: role.team,
        ability: role.ability,
        firstNight: role.firstNight || 0,
        otherNight: role.otherNight || 0,
        firstNightReminder: role.firstNightReminder || "",
        otherNightReminder: role.otherNightReminder || "",
        reminders: Array.isArray(role.reminders)
          ? role.reminders.join(", ")
          : "",
        setup: role.setup || false,
        roleType: role.roleType || (this.isOfficialRole(role.id) ? 'official' : 'custom'), // 加载角色类型，兼容旧数据
      };
    },
    async saveRole() {
      // 验证必填字段
      if (!this.roleForm.id || !this.roleForm.name || !this.roleForm.ability) {
        alert("请填写必填字段：角色ID、名称和能力描述");
        return;
      }

      this.isLoading = true;
      try {
      const roleData = {
        ...this.roleForm,
          id: this.roleForm.id.toLowerCase().replace(/[^a-z0-9]/g, ""), // 清理ID
        reminders: this.roleForm.reminders
          .split(",")
          .map((r) => r.trim())
          .filter((r) => r),
          // 保留用户设置的角色类型，同时为了兼容性也设置isCustom
          isCustom: this.roleForm.roleType === 'custom', // 根据角色类型设置isCustom字段
        };

        // 获取当前所有角色
        const currentRoles = Array.from(this.$store.getters.rolesJSONbyId.values());
        
        if (this.editingRole) {
          // 编辑现有角色
          const roleIndex = currentRoles.findIndex(r => r.id === this.editingRole.id);
          if (roleIndex !== -1) {
            currentRoles[roleIndex] = { ...currentRoles[roleIndex], ...roleData };
          }
        } else {
          // 添加新角色
          if (currentRoles.some(r => r.id === roleData.id)) {
            alert("角色ID已存在，请使用不同的ID");
            return;
          }
          currentRoles.push(roleData);
        }

                // 更新store
        this.$store.commit("setCustomRoles", currentRoles);
        
        // 同时保存到服务器
        try {
          console.log('🔄 同步角色保存操作到服务器...');
          const RolesAPI = (await import('../../utils/rolesAPI.js')).default;
          await RolesAPI.saveUserRoles(currentRoles);
          console.log('✅ 角色保存操作已同步到服务器');
        } catch (serverError) {
          console.warn('⚠️ 同步到服务器失败，但本地数据已更新:', serverError.message);
        }
        
        alert(this.editingRole ? "角色更新成功" : "角色添加成功");
      this.cancelEdit();
      } catch (error) {
        console.error("保存角色失败:", error);
        alert("保存失败，请重试");
      } finally {
        this.isLoading = false;
      }
    },
    cancelEdit() {
      this.showAddRole = false;
      this.editingRole = null;
      this.roleForm = {
        id: "",
        name: "",
        image: "",
        team: "townsfolk",
        ability: "",
        firstNight: 0,
        otherNight: 0,
        firstNightReminder: "",
        otherNightReminder: "",
        reminders: "",
        setup: false,
      };
    },
    async deleteRole(role) {
      const roleTypeText = this.isOfficialRole(role.id) ? '官方角色' : '自定义角色';
      
      if (!confirm(`确定要删除${roleTypeText}"${role.name}"吗？`)) {
        return;
      }

      try {
        console.log("=== 开始删除单个角色 ===");
        console.log("删除目标:", role.id, role.name, "类型:", roleTypeText);
        
        // 获取当前所有角色
        const currentRoles = Array.from(this.$store.getters.rolesJSONbyId.values());
        console.log("删除前角色总数:", currentRoles.length);
        console.log("删除前角色列表:", currentRoles.map(r => r.id));
        
        // 过滤掉要删除的角色
        const filteredRoles = currentRoles.filter(r => r.id !== role.id);
        console.log("删除后剩余角色数:", filteredRoles.length);
        console.log("删除后角色列表:", filteredRoles.map(r => r.id));
        
        // 验证确实删除了目标角色
        const deletedRole = currentRoles.find(r => r.id === role.id);
        const stillExists = filteredRoles.find(r => r.id === role.id);
        console.log("目标角色是否存在于原列表:", !!deletedRole);
        console.log("目标角色是否仍在新列表中:", !!stillExists);
        
        // 更新store
        console.log("正在更新Store...");
        this.$store.commit("setCustomRoles", filteredRoles);
        
        // 同时保存到服务器
        try {
          console.log('🔄 同步删除操作到服务器...');
          const RolesAPI = (await import('../../utils/rolesAPI.js')).default;
          await RolesAPI.saveUserRoles(filteredRoles);
          console.log('✅ 删除操作已同步到服务器');
        } catch (serverError) {
          console.warn('⚠️ 同步到服务器失败，但本地数据已更新:', serverError.message);
        }
        
        // 等待下一个tick确保更新完成
        await this.$nextTick();
        
        // 验证Store是否更新成功
        const updatedRoles = Array.from(this.$store.getters.rolesJSONbyId.values());
        console.log("Store更新后角色总数:", updatedRoles.length);
        console.log("Store更新后是否还包含删除的角色:", updatedRoles.some(r => r.id === role.id));
        
        // 强制触发响应式更新
        this.forceUpdateKey++;
        this.$forceUpdate();
        
        console.log("=== 单个角色删除完成 ===");
        console.log("强制更新key:", this.forceUpdateKey);
        alert(`${roleTypeText}删除成功`);
      } catch (error) {
        console.error("删除角色失败:", error);
        alert("删除失败，请重试");
      }
    },

    // 新增方法：处理logo错误
    handleLogoError(event) {
      event.target.style.display = 'none';
      event.target.parentNode.classList.add('logo-error');
    },

    // 导出角色
    exportRoles() {
      const roles = this.filteredRoles;
      const dataStr = JSON.stringify(roles, null, 2);
      const blob = new Blob([dataStr], { type: 'application/json' });
      const url = URL.createObjectURL(blob);
      
      const link = document.createElement('a');
      link.href = url;
      link.download = `roles_export_${new Date().toISOString().split('T')[0]}.json`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
    },

    // 剧本导入相关方法
    handleScriptFile(event) {
      const file = event.target.files[0];
      if (!file) return;

      const reader = new FileReader();
      reader.onload = (e) => {
        try {
          const script = JSON.parse(e.target.result);
          this.processScriptData(script);
        } catch (error) {
          console.error("解析剧本文件失败:", error);
          alert("剧本文件格式错误，请检查文件内容");
        }
      };
      reader.readAsText(file);
    },

    processScriptData(script) {
      // 解析剧本中的角色数据
      let roles = [];
      
      if (Array.isArray(script)) {
        // 直接是角色数组
        roles = script;
      } else if (script.content && Array.isArray(script.content)) {
        // 标准剧本格式
        roles = script.content;
      } else if (script.roles && Array.isArray(script.roles)) {
        // 其他格式
        roles = script.roles;
      }

      // 处理角色数据，添加选中状态
      this.scriptPreview = roles
        .filter(role => role && (role.id || role.name))
        .map(role => ({
          ...role,
          selected: true, // 默认选中
        }));

      if (this.scriptPreview.length === 0) {
        alert("未在剧本文件中找到有效的角色数据");
      }
    },

    getPreviewRoleIcon(role) {
      if (role.image) {
        return role.image;
      }
      try {
        return require(`../../assets/icons/${role.id}.png`);
      } catch {
        return require("../../assets/icons/custom.png");
      }
    },

    handlePreviewImageError(event) {
      event.target.src = require("../../assets/icons/custom.png");
    },

    selectAllRoles() {
      this.scriptPreview.forEach(role => {
        role.selected = true;
      });
    },

    deselectAllRoles() {
      this.scriptPreview.forEach(role => {
        role.selected = false;
      });
    },

    async importSelectedRoles() {
      const selectedRoles = this.scriptPreview.filter(role => role.selected);
      
      if (selectedRoles.length === 0) {
        alert("请至少选择一个角色进行导入");
        return;
      }

      try {
        this.isLoading = true;
        
        // 获取当前所有角色
        const currentRoles = Array.from(this.$store.getters.rolesJSONbyId.values());
        
        let importedCount = 0;
        let skippedCount = 0;
        
        // 处理每个选中的角色
        selectedRoles.forEach(role => {
          // 清理角色ID
          const cleanId = role.id ? role.id.toLowerCase().replace(/[^a-z0-9]/g, "") : null;
          
          if (!cleanId || !role.name || !role.ability) {
            skippedCount++;
            return;
          }
          
          // 检查是否已存在
          if (currentRoles.some(r => r.id === cleanId)) {
            skippedCount++;
            return;
          }
          
          // 添加角色 - 现在支持设置角色类型
          const roleData = {
            ...role,
            id: cleanId,
            // 角色类型可以在导入时指定，默认为自定义
            roleType: role.roleType || 'custom',
            isCustom: (role.roleType !== 'official'), // 基于roleType确定isCustom
            reminders: Array.isArray(role.reminders) ? role.reminders : [],
            firstNight: Math.abs(role.firstNight || 0),
            otherNight: Math.abs(role.otherNight || 0),
          };
          
          // 验证和处理图片URL
          if (role.image) {
            console.log(`角色 ${role.name} (${cleanId}) 包含图片:`, role.image);
            // 确保图片URL有效
            try {
              new URL(role.image); // 仅用于验证URL格式，无需保存
              roleData.image = role.image;
              console.log(`✅ 角色 ${cleanId} 图片URL有效:`, role.image);
            } catch (e) {
              console.warn(`⚠️ 角色 ${cleanId} 图片URL无效:`, role.image, '错误:', e.message);
              // 保留原始图片信息，让浏览器尝试加载
              roleData.image = role.image;
            }
          } else {
            console.log(`角色 ${role.name} (${cleanId}) 无自定义图片，将使用默认图标`);
          }
          
          currentRoles.push(roleData);
          importedCount++;
        });
        
        // 验证导入的角色数据
        console.log(`📊 即将保存 ${currentRoles.length} 个角色到Store:`);
        currentRoles.slice(-Math.min(3, importedCount)).forEach(role => {
          console.log(`  - ${role.id} (${role.roleType}): ${role.name} - ${role.ability?.substring(0, 30)}...`);
        });
        
        // 更新store
        this.$store.commit("setCustomRoles", currentRoles);
        
        // 验证Store更新
        const storeRoles = Array.from(this.$store.getters.rolesJSONbyId.values());
        console.log(`✅ Store更新完成，当前包含 ${storeRoles.length} 个角色`);
        
        // 同时保存到服务器
        try {
          console.log('🔄 同步导入的角色数据到服务器...');
          const RolesAPI = (await import('../../utils/rolesAPI.js')).default;
          const saveResult = await RolesAPI.saveUserRoles(currentRoles);
          console.log('✅ 角色数据已同步到服务器:', saveResult);
        } catch (serverError) {
          console.warn('⚠️ 保存到服务器失败，但本地数据已更新:', serverError.message);
          // 不阻塞用户操作，服务器同步失败也能继续使用
        }
        
        // 强制刷新UI以显示新导入的角色和图片
        await this.$nextTick();
        this.forceUpdateKey++;
        this.$forceUpdate();
        
        // 清空图片加载状态，让新角色重新加载图片
        this.imageLoadingStates = {};
        
        alert(`导入完成！成功导入 ${importedCount} 个角色（${selectedRoles.filter(r => r.image).length} 个包含自定义图片），跳过 ${skippedCount} 个角色`);
        this.cancelScriptImport();
        
      } catch (error) {
        console.error("导入角色失败:", error);
        alert("导入失败，请重试");
      } finally {
        this.isLoading = false;
      }
    },

    cancelScriptImport() {
      this.showScriptImport = false;
      this.scriptPreview = [];
    },

    // 判断角色是否为官方角色（基于用户设置的标签）
    isOfficialRole(roleId) {
      const role = this.$store.getters.rolesJSONbyId.get(roleId);
      if (!role) return false;
      
      // 优先使用用户设置的角色类型标签
      if (role.roleType) {
        return role.roleType === 'official';
      }
      
      // 兼容旧数据：如果没有roleType字段，使用原有逻辑作为默认值
      // 但现在所有角色都可以被编辑，这里只是为了显示标签
      if (role.edition) return true;
      if (role.isCustom === false) return true;
      
      const hasOfficialStructure = Object.prototype.hasOwnProperty.call(role, 'edition') || 
                                   Object.prototype.hasOwnProperty.call(role, 'firstNight') || 
                                   Object.prototype.hasOwnProperty.call(role, 'otherNight');
      
      return hasOfficialStructure && role.isCustom !== true;
    },

    // 批量选择功能
    toggleSelectAll() {
      if (this.isAllSelected) {
        this.selectedRoles = [];
      } else {
        this.selectedRoles = this.filteredRoles.map(role => role.id);
      }
    },

    clearSelection() {
      this.selectedRoles = [];
    },

    updateSelection() {
      // 当选择发生变化时，确保选中的角色仍在当前过滤结果中
      const currentRoleIds = this.filteredRoles.map(role => role.id);
      this.selectedRoles = this.selectedRoles.filter(id => currentRoleIds.includes(id));
    },

    // 批量删除功能
    async batchDelete() {
      if (this.selectedRoles.length === 0) {
        alert('请先选择要删除的角色');
        return;
      }

      const selectedRoleNames = this.selectedRoleObjects.map(role => {
        const roleType = this.isOfficialRole(role.id) ? '[官方]' : '[自定义]';
        return `${roleType} ${role.name}`;
      }).join('\n');
      
      const confirmMessage = `确定要删除以下 ${this.selectedRoles.length} 个角色吗？\n\n${selectedRoleNames}`;
      
      if (!confirm(confirmMessage)) {
        return;
      }

      try {
        this.isLoading = true;
        console.log("=== 开始批量删除角色 ===");
        console.log("选中的角色对象:", this.selectedRoleObjects.map(r => ({ id: r.id, name: r.name })));
        
        // 获取当前所有角色
        const currentRoles = Array.from(this.$store.getters.rolesJSONbyId.values());
        console.log("删除前角色总数:", currentRoles.length);
        console.log("删除前角色列表:", currentRoles.map(r => r.id));
        
        // 获取要删除的角色ID列表
        const roleIdsToDelete = this.selectedRoles;
        console.log("要删除的角色ID列表:", roleIdsToDelete);
        
        // 验证选中的角色确实存在
        const existingRolesToDelete = currentRoles.filter(role => roleIdsToDelete.includes(role.id));
        console.log("实际存在的待删除角色:", existingRolesToDelete.map(r => ({ id: r.id, name: r.name })));
        
        // 过滤掉选中要删除的角色，保留其他所有角色
        const remainingRoles = currentRoles.filter(role => {
          const shouldKeep = !roleIdsToDelete.includes(role.id);
          if (!shouldKeep) {
            const roleType = this.isOfficialRole(role.id) ? '官方' : '自定义';
            console.log("删除角色:", role.id, role.name, "类型:", roleType);
          }
          return shouldKeep;
        });
        
        console.log("删除后剩余角色数:", remainingRoles.length);
        console.log("删除后角色列表:", remainingRoles.map(r => r.id));
        
        // 验证删除的角色数量
        const actualDeletedCount = currentRoles.length - remainingRoles.length;
        console.log("实际删除的角色数量:", actualDeletedCount);
        console.log("预期删除的角色数量:", roleIdsToDelete.length);
        
        // 更新store
        console.log("正在更新Store...");
        this.$store.commit("setCustomRoles", remainingRoles);
        
        // 同时保存到服务器
        try {
          console.log('🔄 同步批量删除操作到服务器...');
          const RolesAPI = (await import('../../utils/rolesAPI.js')).default;
          await RolesAPI.saveUserRoles(remainingRoles);
          console.log('✅ 批量删除操作已同步到服务器');
        } catch (serverError) {
          console.warn('⚠️ 同步到服务器失败，但本地数据已更新:', serverError.message);
        }
        
        // 等待下一个tick确保更新完成
        await this.$nextTick();
        
        // 验证Store是否更新成功
        const updatedRoles = Array.from(this.$store.getters.rolesJSONbyId.values());
        console.log("Store更新后角色总数:", updatedRoles.length);
        
        // 检查被删除的角色是否还存在
        const stillExistingRoles = roleIdsToDelete.filter(id => 
          updatedRoles.some(r => r.id === id)
        );
        if (stillExistingRoles.length > 0) {
          console.error("以下角色删除失败，仍然存在:", stillExistingRoles);
        } else {
          console.log("所有目标角色已成功删除");
        }
        
        // 强制触发响应式更新
        this.forceUpdateKey++;
        this.$forceUpdate();
        
        // 清除选择并显示成功信息
        const deletedCount = this.selectedRoles.length;
        this.selectedRoles = [];
        
        console.log("=== 批量删除完成 ===");
        console.log("强制更新key:", this.forceUpdateKey);
        alert(`成功删除 ${deletedCount} 个角色`);
        
      } catch (error) {
        console.error("批量删除角色失败:", error);
        alert("删除失败，请重试");
      } finally {
        this.isLoading = false;
      }
    },

    // 批量导出功能
    batchExport() {
      if (this.selectedRoles.length === 0) {
        alert('请先选择要导出的角色');
        return;
      }

      const selectedRoleData = this.selectedRoleObjects;
      const dataStr = JSON.stringify(selectedRoleData, null, 2);
      const blob = new Blob([dataStr], { type: 'application/json' });
      const url = URL.createObjectURL(blob);
      
      const link = document.createElement('a');
      link.href = url;
      link.download = `selected_roles_${this.selectedRoles.length}_${new Date().toISOString().split('T')[0]}.json`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(url);

      alert(`成功导出 ${this.selectedRoles.length} 个角色`);
    },



    // 验证数据一致性的方法
    validateDataConsistency() {
      const storeRoles = Array.from(this.$store.getters.rolesJSONbyId.values());
      const filteredRoles = this.filteredRoles;
      
      console.log("=== 数据一致性检查 ===");
      console.log("Store角色数量:", storeRoles.length);
      console.log("过滤后角色数量:", filteredRoles.length);
      console.log("Store角色ID列表:", storeRoles.map(r => r.id).sort());
      console.log("过滤角色ID列表:", filteredRoles.map(r => r.id).sort());
      
      return {
        storeCount: storeRoles.length,
        filteredCount: filteredRoles.length,
        consistent: storeRoles.length === filteredRoles.length || this.searchQuery || this.teamFilter || this.roleTypeFilter
      };
    },
  },
  
  // 添加生命周期钩子
  mounted() {
    console.log("RoleManager组件已挂载");
    this.validateDataConsistency();
  },
  
  // 添加更新后钩子
  updated() {
    // 在DOM更新后验证数据一致性（仅在开发环境下）
    if (process.env.NODE_ENV === 'development') {
      this.validateDataConsistency();
    }
  },
};
</script>

<style scoped lang="scss">
@import "../../vars.scss";

// 定义主题变量
$gold: #ffd700;
$darkBackground: rgba(0, 0, 0, 0.8);

.role-manager {
  .role-header {
    margin-bottom: 20px;

    // 批量操作区域样式
    .batch-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
      padding: 15px 20px;
      margin-bottom: 15px;
      background: rgba(255, 215, 0, 0.05);
      border: 1px solid rgba(255, 215, 0, 0.2);
      border-radius: 8px;
      animation: slideInDown 0.3s ease-out;

      .selection-info {
        display: flex;
        align-items: center;
        gap: 15px;

        .selected-count {
          color: #ffd700;
          font-weight: bold;
          font-family: "Papyrus", serif;
        }

        .clear-selection {
          padding: 4px 12px;
          border: 1px solid rgba(255, 215, 0, 0.3);
          background: rgba(255, 255, 255, 0.1);
          color: rgba(255, 255, 255, 0.8);
          border-radius: 4px;
          cursor: pointer;
          font-family: "Papyrus", serif;
          font-size: 12px;
          transition: all 0.3s ease;

          &:hover {
            background: rgba(255, 255, 255, 0.2);
            color: white;
          }
        }
      }

      .batch-buttons {
        display: flex;
        gap: 10px;

        .batch-delete-btn {
          padding: 8px 16px;
          border: 1px solid #e74c3c;
          background: rgba(231, 76, 60, 0.2);
          color: #e74c3c;
          border-radius: 5px;
          cursor: pointer;
          font-family: "Papyrus", serif;
          font-size: 14px;
          transition: all 0.3s ease;

          &:hover {
            background: rgba(231, 76, 60, 0.3);
            color: white;
            transform: translateY(-1px);
          }
        }

        .batch-export-btn {
          padding: 8px 16px;
          border: 1px solid #3498db;
          background: rgba(52, 152, 219, 0.2);
          color: #3498db;
          border-radius: 5px;
          cursor: pointer;
          font-family: "Papyrus", serif;
          font-size: 14px;
          transition: all 0.3s ease;

          &:hover {
            background: rgba(52, 152, 219, 0.3);
            color: white;
            transform: translateY(-1px);
          }
        }
      }
    }

    // 主要搜索和操作区域
    .search-section,
    .header-actions {
      display: flex;
      gap: 10px;
      align-items: center;
    }

    & > * {
      margin-bottom: 10px;
    }

    & > *:last-child {
      margin-bottom: 0;
    }

    .search-section {
      display: flex;
      gap: 10px;

      .search-input {
        padding: 8px 12px;
        border: 1px solid rgba(255, 215, 0, 0.3);
        background: rgba(0, 0, 0, 0.6);
        color: white;
        border-radius: 5px;
        font-family: "Papyrus", serif;
        width: 200px;
        transition: all 0.3s;

        &:hover {
          border-color: rgba(255, 215, 0, 0.5);
          background: rgba(0, 0, 0, 0.7);
        }

        &:focus {
          outline: none;
          border-color: rgba(255, 215, 0, 0.8);
          background: rgba(0, 0, 0, 0.8);
          box-shadow: 0 0 0 2px rgba(255, 215, 0, 0.2);
        }

        &::placeholder {
          color: rgba(255, 255, 255, 0.5);
        }
      }

      .team-filter {
        padding: 8px 12px;
        border: 1px solid rgba(255, 215, 0, 0.3);
        background: rgba(0, 0, 0, 0.8);
        color: white;
        border-radius: 5px;
        font-family: "Papyrus", serif;
        cursor: pointer;

        option {
          background: rgba(0, 0, 0, 0.9);
          color: white;
          padding: 8px 12px;
        }

        &:focus {
          outline: none;
          border-color: #ffd700;
          box-shadow: 0 0 8px rgba(255, 215, 0, 0.3);
        }
      }

      .role-type-filter {
        padding: 8px 12px;
        border: 1px solid rgba(155, 89, 182, 0.3);
        background: rgba(0, 0, 0, 0.8);
        color: white;
        border-radius: 5px;
        font-family: "Papyrus", serif;
        cursor: pointer;
        min-width: 140px;

        option {
          background: rgba(0, 0, 0, 0.9);
          color: white;
          padding: 8px 12px;
        }

        &:focus {
          outline: none;
          border-color: #9b59b6;
          box-shadow: 0 0 8px rgba(155, 89, 182, 0.3);
        }

        &:hover {
          border-color: rgba(155, 89, 182, 0.5);
        }
      }
    }

    .header-actions {
      display: flex;
      gap: 10px;
      
                  .refresh-btn, .load-server-btn, .select-all-btn, .import-btn, .export-btn, .add-btn {
      padding: 8px 16px;
      border-radius: 5px;
      cursor: pointer;
      font-family: "Papyrus", serif;
        border: 1px solid;
        transition: all 0.3s ease;
      }



      .select-all-btn {
        background: rgba(106, 90, 205, 0.2);
        border-color: #6a5acd;
        color: #6a5acd;

        &:hover {
          background: rgba(106, 90, 205, 0.3);
          color: white;
        }

        &.active {
          background: rgba(106, 90, 205, 0.4);
          color: white;
          border-color: #6a5acd;
        }
      }

      .import-btn {
        background: rgba(52, 152, 219, 0.2);
        border-color: #3498db;
        color: #3498db;

        &:hover {
          background: rgba(52, 152, 219, 0.3);
          color: white;
        }
      }

      .export-btn {
        background: rgba(155, 89, 182, 0.2);
        border-color: #9b59b6;
        color: #9b59b6;

        &:hover {
          background: rgba(155, 89, 182, 0.3);
          color: white;
        }
      }

      .add-btn {
        background: rgba(255, 215, 0, 0.2);
        border-color: #ffd700;
        color: #ffd700;

      &:hover {
        background: rgba(255, 215, 0, 0.3);
        color: white;
        }
      }
    }
  }

  .role-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
    gap: 24px;
    align-items: start;
    padding: 0 12px;

    .role-item {
      background: linear-gradient(135deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.08) 100%);
      border: 1px solid rgba(255, 215, 0, 0.2);
      border-radius: 16px;
      padding: 24px;
      cursor: pointer;
      transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
      position: relative;
      min-height: auto;
      backdrop-filter: blur(8px);
      box-shadow: 
        0 4px 20px rgba(0, 0, 0, 0.1),
        inset 0 1px 0 rgba(255, 255, 255, 0.1);
      display: grid;
      grid-template-columns: auto 1fr auto;
      grid-template-areas: 
        "icon header actions"
        "icon ability actions";
      gap: 24px;

      &:hover {
        background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.15) 100%);
        border-color: rgba(255, 215, 0, 0.5);
        box-shadow: 
          0 8px 32px rgba(255, 215, 0, 0.2),
          0 2px 16px rgba(0, 0, 0, 0.15),
          inset 0 1px 0 rgba(255, 255, 255, 0.2);
        transform: translateY(-4px) scale(1.02);
        
        .role-info h4 {
          color: #fff;
          text-shadow: 0 0 12px rgba(255, 215, 0, 0.6);
        }
        
        .role-icon {
          transform: scale(1.05);
          box-shadow: 0 0 20px rgba(255, 215, 0, 0.3);
        }
      }

      &.selected {
        background: rgba(255, 215, 0, 0.1);
        border-color: rgba(255, 215, 0, 0.5);
        box-shadow: 0 0 12px rgba(255, 215, 0, 0.2);

        .role-info h4 {
          color: #ffd700;
          text-shadow: 0 0 8px rgba(255, 215, 0, 0.3);
        }
      }

      // 角色选择复选框样式
      .role-selection {
        display: flex;
        align-items: center;
        margin-top: 5px;

        .role-checkbox {
          position: relative;
          cursor: pointer;
          user-select: none;

          input[type="checkbox"] {
            position: absolute;
            opacity: 0;
            cursor: pointer;
            height: 0;
            width: 0;
          }

          .checkbox-custom {
            position: relative;
            display: inline-block;
            width: 20px;
            height: 20px;
        background: rgba(255, 255, 255, 0.1);
            border: 2px solid rgba(255, 215, 0, 0.3);
            border-radius: 4px;
            transition: all 0.3s ease;

            &::after {
              content: "";
              position: absolute;
              display: none;
              left: 6px;
              top: 2px;
              width: 6px;
              height: 10px;
              border: solid #ffd700;
              border-width: 0 2px 2px 0;
              transform: rotate(45deg);
            }
          }

          input:checked ~ .checkbox-custom {
            background: rgba(255, 215, 0, 0.2);
            border-color: #ffd700;

            &::after {
              display: block;
            }
          }

          input:hover ~ .checkbox-custom {
            border-color: rgba(255, 215, 0, 0.5);
            background: rgba(255, 255, 255, 0.15);
          }
        }
      }

      .role-icon {
        width: 80px;
        height: 80px;
        flex-shrink: 0;
        position: relative;
        display: flex;
        align-items: center;
        justify-content: center;
        background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.12) 100%);
        border-radius: 12px;
        overflow: hidden;
        border: 2px solid rgba(255, 215, 0, 0.2);
        transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        box-shadow: 
          0 4px 12px rgba(0, 0, 0, 0.15),
          inset 0 1px 0 rgba(255, 255, 255, 0.2);

        .role-image {
          width: 100%;
          height: 100%;
          object-fit: cover;
          border-radius: 10px;
          transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);

          &.image-error {
            opacity: 0.6;
            filter: grayscale(100%);
          }

          &:hover {
            transform: scale(1.08);
          }
        }

        // 悬停时的增强效果
        &:hover {
          border-color: rgba(255, 215, 0, 0.4);
          box-shadow: 
            0 0 24px rgba(255, 215, 0, 0.3),
            0 8px 20px rgba(0, 0, 0, 0.2),
            inset 0 1px 0 rgba(255, 255, 255, 0.3);
          transform: translateY(-2px) scale(1.02);
        }

        .image-loading {
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
          font-size: 16px;
          color: rgba(255, 215, 0, 0.8);
          animation: pulse 1.5s ease-in-out infinite;
          z-index: 1;
        }

        // 加载状态样式（通过JavaScript动态添加类名）
        &.loading-state {
          background: radial-gradient(circle, rgba(255, 215, 0, 0.1) 0%, rgba(255, 215, 0, 0.05) 70%);
        }

        // 错误状态边框（通过JavaScript动态添加类名）
        &.error-state {
          border: 1px solid rgba(231, 76, 60, 0.3);
          background: rgba(231, 76, 60, 0.05);
        }
      }

      // 脉冲动画用于加载状态
      @keyframes pulse {
        0%, 100% {
          opacity: 0.4;
          transform: translate(-50%, -50%) scale(1);
        }
        50% {
          opacity: 1;
          transform: translate(-50%, -50%) scale(1.1);
        }
      }

            .role-icon {
        grid-area: icon;
        align-self: start;
      }

      .role-header {
        grid-area: header;
        display: flex;
        flex-direction: column;
        gap: 12px;
        min-width: 0;

        .role-title {
          display: flex;
          align-items: center;
          gap: 12px;
          margin-bottom: 0;

          h4 {
            color: #ffd700;
            margin: 0;
            font-size: 20px;
            font-weight: 700;
            transition: all 0.3s ease;
            flex: 1;
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
            letter-spacing: 0.5px;
            line-height: 1.2;
          }

          .role-badge {
            padding: 3px 8px;
            border-radius: 4px;
            font-size: 11px;
            font-weight: bold;
            text-transform: uppercase;
            letter-spacing: 0.5px;
            flex-shrink: 0;
            transition: all 0.3s ease;

            &.official {
              background: rgba(52, 152, 219, 0.3);
              color: #5dade2;
              border: 1px solid rgba(52, 152, 219, 0.5);
              box-shadow: 0 1px 3px rgba(52, 152, 219, 0.2);
            }

            &.custom {
              background: rgba(155, 89, 182, 0.3);
              color: #bb8fce;
              border: 1px solid rgba(155, 89, 182, 0.5);
              box-shadow: 0 1px 3px rgba(155, 89, 182, 0.2);
            }
          }
        }

        .role-team {
          color: rgba(255, 255, 255, 0.8);
          font-size: 14px;
          margin: 0;
          font-weight: 600;
          text-transform: capitalize;
          padding: 6px 12px;
          background: rgba(255, 255, 255, 0.1);
          border-radius: 6px;
          display: inline-block;
          align-self: flex-start;
          backdrop-filter: blur(4px);
          border: 1px solid rgba(255, 255, 255, 0.15);
        }
      }

      .role-ability-container {
        grid-area: ability;
        grid-column: 2 / -2; // 从第二列跨到倒数第二列
        align-self: start;
        margin-top: -8px; // 减少与上方内容的间距
        
        .role-ability {
          color: rgba(255, 255, 255, 0.95);
          font-size: 15px;
          margin: 0;
          line-height: 1.7;
          font-family: inherit;
          padding: 8px 0;
          position: relative;
          word-break: break-word;
          white-space: pre-wrap; // 保持文本格式
          text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
          letter-spacing: 0.3px;
        }
      }

      .role-actions {
        grid-area: actions;
        align-self: start;
      }

      .role-actions {
        display: flex;
        flex-direction: column;
        gap: 10px;
        flex-shrink: 0;
        align-self: center;
        min-width: 80px;

        .edit-btn,
        .delete-btn {
          padding: 10px 16px;
          border: none;
          border-radius: 8px;
          cursor: pointer;
          font-family: inherit;
          font-size: 13px;
          font-weight: 600;
          transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
          backdrop-filter: blur(4px);
          box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
          text-transform: capitalize;
          letter-spacing: 0.5px;
          border: 1px solid transparent;
        }

        .edit-btn {
          background: linear-gradient(135deg, rgba(76, 175, 80, 0.2) 0%, rgba(76, 175, 80, 0.3) 100%);
          color: #66bb6a;
          border-color: rgba(76, 175, 80, 0.3);

          &:hover {
            background: linear-gradient(135deg, rgba(76, 175, 80, 0.3) 0%, rgba(76, 175, 80, 0.4) 100%);
            color: #fff;
            transform: translateY(-2px) scale(1.05);
            box-shadow: 0 4px 16px rgba(76, 175, 80, 0.3);
            border-color: rgba(76, 175, 80, 0.5);
          }
        }

        .delete-btn {
          background: linear-gradient(135deg, rgba(244, 67, 54, 0.2) 0%, rgba(244, 67, 54, 0.3) 100%);
          color: #ef5350;
          border-color: rgba(244, 67, 54, 0.3);

          &:hover {
            background: linear-gradient(135deg, rgba(244, 67, 54, 0.3) 0%, rgba(244, 67, 54, 0.4) 100%);
            color: #fff;
            transform: translateY(-2px) scale(1.05);
            box-shadow: 0 4px 16px rgba(244, 67, 54, 0.3);
            border-color: rgba(244, 67, 54, 0.5);
          }
        }
      }
    }

    // 空状态样式
    .empty-state {
      grid-column: 1 / -1;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      text-align: center;
      color: rgba(255, 255, 255, 0.6);
      font-size: 16px;
      min-height: 300px;
      animation: fadeInUp 0.6s ease-out;

      .empty-icon {
        font-size: 64px;
        margin-bottom: 20px;
        opacity: 0.7;
        animation: float 3s ease-in-out infinite;
      }

      h3 {
        color: #ffd700;
        margin: 0 0 10px 0;
        font-size: 24px;
        font-family: "Papyrus", serif;
      }

      p {
        margin: 0 0 20px 0;
        max-width: 400px;
        line-height: 1.5;
      }

      .add-first-role {
        padding: 12px 24px;
        border: 1px solid #ffd700;
        background: rgba(255, 215, 0, 0.2);
        color: #ffd700;
        border-radius: 6px;
        cursor: pointer;
        font-family: "Papyrus", serif;
        font-size: 16px;
        transition: all 0.3s ease;

        &:hover {
          background: rgba(255, 215, 0, 0.3);
          color: white;
          transform: translateY(-2px);
          box-shadow: 0 4px 12px rgba(255, 215, 0, 0.2);
        }
      }
    }
  }
}

.role-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1100;

  .modal-content {
    background: rgba(0, 0, 0, 0.95);
    border: 2px solid #gold;
    border-radius: 10px;
    padding: 30px;
    width: 90vw;
    max-width: 600px;
    max-height: 80vh;
    overflow-y: auto;
    color: white;

    .modal-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20px;

      h3 {
        color: #gold;
        margin: 0;
      }

      .close-btn {
        background: none;
        border: none;
        color: #gold;
        font-size: 24px;
        cursor: pointer;
        padding: 5px;

        &:hover {
          color: white;
        }
      }
    }

    .form-group {
      margin-bottom: 15px;

      label {
        display: block;
        margin-bottom: 5px;
        color: #gold;
        font-size: 14px;
      }

      input,
      textarea {
        width: 100%;
        padding: 8px 12px;
        border: 1px solid rgba(255, 215, 0, 0.3);
        background: rgba(255, 255, 255, 0.1);
        color: white;
        border-radius: 5px;
        font-family: "Papyrus", serif;

        &::placeholder {
          color: rgba(255, 255, 255, 0.5);
        }
      }

      select {
        width: 100%;
        padding: 8px 12px;
        border: 1px solid rgba(255, 215, 0, 0.3);
        background: rgba(0, 0, 0, 0.8);
        color: white;
        border-radius: 5px;
        font-family: "Papyrus", serif;
        cursor: pointer;

        option {
          background: rgba(0, 0, 0, 0.9);
          color: white;
          padding: 8px 12px;
        }

        &:focus {
          outline: none;
          border-color: #gold;
          box-shadow: 0 0 8px rgba(255, 215, 0, 0.3);
        }

        &.role-type-select {
          border-color: rgba(155, 89, 182, 0.3);
          
          &:focus {
            border-color: #9b59b6;
            box-shadow: 0 0 8px rgba(155, 89, 182, 0.3);
          }

          &:hover {
            border-color: rgba(155, 89, 182, 0.5);
          }
        }
      }

      textarea {
        min-height: 80px;
        resize: vertical;
      }

      // Logo 输入组件样式
      .logo-input-group {
        display: flex;
        gap: 15px;
        align-items: flex-start;

        .logo-input {
          flex: 1;
        }

        .logo-preview {
          width: 60px;
          height: 60px;
          border: 1px solid rgba(255, 215, 0, 0.3);
          border-radius: 5px;
          overflow: hidden;
          background: rgba(255, 255, 255, 0.05);
          display: flex;
          align-items: center;
          justify-content: center;

          img {
            width: 100%;
            height: 100%;
            object-fit: cover;
          }

          &.logo-error {
            &::after {
              content: "❌";
              color: #f44336;
              font-size: 20px;
            }
          }
        }
      }

      .form-hint {
        color: rgba(255, 255, 255, 0.6);
        font-size: 12px;
        margin-top: 5px;
        display: block;
      }

      .file-input {
        padding: 8px 0;
        background: none;
        border: 1px dashed rgba(255, 215, 0, 0.3);
        border-radius: 5px;
        color: white;
        
        &:hover {
          border-color: rgba(255, 215, 0, 0.5);
        }
      }
    }

    .modal-actions {
      display: flex;
      gap: 10px;
      margin-top: 20px;

      .save-btn,
      .cancel-btn {
        padding: 10px 20px;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        font-family: "Papyrus", serif;
      }

      .save-btn {
        background: rgba(76, 175, 80, 0.2);
        color: #4caf50;

        &:hover {
          background: rgba(76, 175, 80, 0.3);
        }
      }

      .cancel-btn {
        background: rgba(255, 255, 255, 0.1);
        color: rgba(255, 255, 255, 0.8);

        &:hover {
          background: rgba(255, 255, 255, 0.2);
        }
      }
    }
  }
}

// 剧本导入相关样式
.import-section {
  .preview-section {
    margin-top: 20px;
    
    h4 {
      color: #ffd700;
      margin-bottom: 15px;
      font-size: 16px;
    }
    
    .script-roles-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
      gap: 10px;
      max-height: 400px;
      overflow-y: auto;
      margin-bottom: 20px;
      padding: 10px;
      border: 1px solid rgba(255, 215, 0, 0.2);
      border-radius: 5px;
      background: rgba(255, 255, 255, 0.02);
      
      .preview-role {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 10px;
        background: rgba(255, 255, 255, 0.05);
        border-radius: 5px;
        border: 1px solid rgba(255, 215, 0, 0.1);
        
        .preview-role-icon {
          width: 40px;
          height: 40px;
          flex-shrink: 0;
          
          img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            border-radius: 3px;
          }
        }
        
        .preview-role-info {
          flex: 1;
          min-width: 0;
          
          strong {
            color: #ffd700;
            font-size: 14px;
            display: block;
            margin-bottom: 3px;
          }
          
          .preview-role-team {
            color: rgba(255, 255, 255, 0.6);
            font-size: 11px;
            margin-bottom: 5px;
          }
          
          .preview-role-ability {
            color: rgba(255, 255, 255, 0.8);
            font-size: 12px;
            line-height: 1.3;
            overflow: hidden;
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
          }
        }
        
        .preview-role-actions {
          .import-checkbox {
            display: flex;
            align-items: center;
            gap: 5px;
            color: #ffd700;
            cursor: pointer;
            user-select: none;
            
            input[type="checkbox"] {
              width: 16px;
              height: 16px;
              cursor: pointer;
              accent-color: #ffd700;
            }
            
            span {
              font-size: 12px;
            }
          }
        }
      }
    }
    
    .import-actions {
      display: flex;
      gap: 10px;
      justify-content: center;
      flex-wrap: wrap;
      
      .action-btn {
        padding: 8px 16px;
        border: 1px solid rgba(255, 215, 0, 0.5);
        background: rgba(255, 215, 0, 0.1);
        color: #ffd700;
        border-radius: 5px;
        cursor: pointer;
        font-family: "Papyrus", serif;
        font-size: 12px;
        transition: all 0.3s ease;
        
        &:hover {
          background: rgba(255, 215, 0, 0.2);
          color: white;
        }
      }
      
      .import-roles-btn {
        padding: 10px 20px;
        border: 1px solid #27ae60;
        background: rgba(39, 174, 96, 0.2);
        color: #27ae60;
        border-radius: 5px;
        cursor: pointer;
        font-family: "Papyrus", serif;
        font-weight: bold;
        transition: all 0.3s ease;
        
        &:hover:not(:disabled) {
          background: rgba(39, 174, 96, 0.3);
          color: white;
        }
        
        &:disabled {
          opacity: 0.5;
          cursor: not-allowed;
          background: rgba(255, 255, 255, 0.1);
          border-color: rgba(255, 255, 255, 0.3);
          color: rgba(255, 255, 255, 0.5);
        }
      }
    }
  }
}

// 自定义滚动条样式 - 符合金色主题风格
.role-manager {
  // 主滚动条样式
  ::-webkit-scrollbar {
    width: 12px;
    height: 12px;
  }

  ::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.3);
    border-radius: 10px;
    border: 1px solid rgba(255, 215, 0, 0.1);
  }

  ::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, 
      rgba(255, 215, 0, 0.8) 0%, 
      rgba(255, 215, 0, 0.6) 50%, 
      rgba(255, 215, 0, 0.4) 100%
    );
    border-radius: 10px;
    border: 1px solid rgba(255, 215, 0, 0.3);
    box-shadow: 
      inset 0 1px 0 rgba(255, 255, 255, 0.2),
      0 1px 3px rgba(0, 0, 0, 0.3);
    transition: all 0.3s ease;
  }

  ::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(180deg, 
      rgba(255, 215, 0, 0.9) 0%, 
      rgba(255, 215, 0, 0.7) 50%, 
      rgba(255, 215, 0, 0.5) 100%
    );
    border-color: rgba(255, 215, 0, 0.5);
    box-shadow: 
      inset 0 1px 0 rgba(255, 255, 255, 0.3),
      0 2px 6px rgba(255, 215, 0, 0.2);
  }

  ::-webkit-scrollbar-thumb:active {
    background: linear-gradient(180deg, 
      rgba(255, 215, 0, 1) 0%, 
      rgba(255, 215, 0, 0.8) 50%, 
      rgba(255, 215, 0, 0.6) 100%
    );
    border-color: rgba(255, 215, 0, 0.7);
    box-shadow: 
      inset 0 1px 0 rgba(255, 255, 255, 0.4),
      0 1px 2px rgba(0, 0, 0, 0.4);
  }

  ::-webkit-scrollbar-corner {
    background: rgba(0, 0, 0, 0.3);
    border: 1px solid rgba(255, 215, 0, 0.1);
  }

  // 角色模态框内的滚动条
  .role-modal {
    ::-webkit-scrollbar {
      width: 8px;
      height: 8px;
    }

    ::-webkit-scrollbar-track {
      background: rgba(255, 255, 255, 0.05);
      border-radius: 6px;
    }

    ::-webkit-scrollbar-thumb {
      background: linear-gradient(180deg, 
        rgba(255, 215, 0, 0.6) 0%, 
        rgba(255, 215, 0, 0.4) 100%
      );
      border-radius: 6px;
      border: 1px solid rgba(255, 215, 0, 0.2);
    }

    ::-webkit-scrollbar-thumb:hover {
      background: linear-gradient(180deg, 
        rgba(255, 215, 0, 0.8) 0%, 
        rgba(255, 215, 0, 0.6) 100%
      );
      border-color: rgba(255, 215, 0, 0.4);
    }
  }

  // 剧本导入滚动区域的滚动条
  .script-roles-grid {
    ::-webkit-scrollbar {
      width: 6px;
    }

    ::-webkit-scrollbar-track {
      background: rgba(0, 0, 0, 0.2);
      border-radius: 3px;
    }

    ::-webkit-scrollbar-thumb {
      background: rgba(255, 215, 0, 0.5);
      border-radius: 3px;
      transition: background 0.3s ease;
    }

    ::-webkit-scrollbar-thumb:hover {
      background: rgba(255, 215, 0, 0.7);
    }
  }
}

// 为Firefox提供滚动条样式
.role-manager {
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 215, 0, 0.6) rgba(0, 0, 0, 0.3);
}

.role-manager .role-modal {
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 215, 0, 0.5) rgba(255, 255, 255, 0.05);
}

.role-manager .script-roles-grid {
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 215, 0, 0.5) rgba(0, 0, 0, 0.2);
}

// 滚动条动画效果
@keyframes scrollbarGlow {
  0%, 100% {
    box-shadow: 
      inset 0 1px 0 rgba(255, 255, 255, 0.2),
      0 1px 3px rgba(0, 0, 0, 0.3);
  }
  50% {
    box-shadow: 
      inset 0 1px 0 rgba(255, 255, 255, 0.3),
      0 2px 8px rgba(255, 215, 0, 0.3);
  }
}

// 滚动时的视觉提示
.role-manager::-webkit-scrollbar-thumb:active {
  animation: scrollbarGlow 0.6s ease-in-out;
}

// 新增动画关键帧
@keyframes slideInDown {
  0% {
    opacity: 0;
    transform: translateY(-20px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes float {
  0%, 100% {
    transform: translateY(0px);
  }
  50% {
    transform: translateY(-10px);
  }
}

// 信息横幅样式
.info-banner {
  background: linear-gradient(135deg, rgba(255, 215, 0, 0.1), rgba(255, 165, 0, 0.05));
  border: 2px solid rgba(255, 215, 0, 0.3);
  border-radius: 15px;
  padding: 25px;
  margin: 20px 0;
  box-shadow: 0 8px 25px rgba(255, 215, 0, 0.1);
  
  .banner-content {
    text-align: center;
    margin-bottom: 20px;
    
    h3 {
      color: $gold;
      margin-bottom: 15px;
      font-size: 1.5em;
      text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
    }
    
    p {
      color: rgba(255, 255, 255, 0.9);
      margin-bottom: 20px;
      font-size: 1.1em;
      line-height: 1.6;
    }
    
    .info-actions {
      display: flex;
      gap: 15px;
      justify-content: center;
      flex-wrap: wrap;
      
      .info-btn, .import-btn {
        padding: 12px 24px;
        border-radius: 8px;
        cursor: pointer;
        font-family: "Papyrus", serif;
        border: 2px solid;
        transition: all 0.3s ease;
        font-size: 1em;
        
        &.info-btn {
          background: rgba(70, 130, 180, 0.2);
          border-color: #4682b4;
          color: #4682b4;
          
          &:hover {
            background: rgba(70, 130, 180, 0.3);
            color: white;
            transform: translateY(-2px);
            box-shadow: 0 6px 15px rgba(70, 130, 180, 0.3);
          }
        }
        
        &.import-btn {
          background: rgba(34, 139, 34, 0.2);
          border-color: #228b22;
          color: #228b22;
          
          &:hover {
            background: rgba(34, 139, 34, 0.3);
            color: white;
            transform: translateY(-2px);
            box-shadow: 0 6px 15px rgba(34, 139, 34, 0.3);
          }
        }
      }
    }
  }
  
  .official-roles-info {
    background: rgba(0, 0, 0, 0.3);
    border-radius: 10px;
    padding: 20px;
    margin-top: 20px;
    
    h4 {
      color: $gold;
      margin-bottom: 15px;
      font-size: 1.3em;
      display: flex;
      align-items: center;
      gap: 10px;
    }
    
    ol {
      color: rgba(255, 255, 255, 0.9);
      line-height: 1.8;
      
      li {
        margin-bottom: 10px;
        
        strong {
          color: $gold;
        }
        
        .download-link {
          color: #4682b4;
          text-decoration: none;
          padding: 5px 10px;
          background: rgba(70, 130, 180, 0.1);
          border-radius: 5px;
          transition: all 0.3s ease;
          
          &:hover {
            background: rgba(70, 130, 180, 0.2);
            color: white;
          }
        }
      }
    }
    
    .tip {
      background: rgba(255, 215, 0, 0.1);
      border-left: 4px solid $gold;
      padding: 15px;
      margin-top: 15px;
      border-radius: 5px;
      color: rgba(255, 255, 255, 0.9);
      font-style: italic;
    }
  }
}
</style>
